#include <sysregs.h>
#include <arch/cpu.h>
#include <plat.h>

void mmu_tcr_init(void)
{
    uint64_t mair;

    /* 0 -> Device-nGnRE */
    mair = MAIR_ATTR_SET(MAIR_DEV_nGnRE, ATTR_DEVICE_nGnRE_INDEX);
    /* 1 -> Normal Memory, Outer Write-Back non-transient, Inner Write-Back non-transient */
    mair |= MAIR_ATTR_SET(MAKE_MAIR_NORMAL_MEMORY(MAIR_NORM_WB_NTR_RWA,MAIR_NORM_WB_NTR_RWA), ATTR_NORMAL_INDEX);
    /* 2 -> Normal Memory, Outer Write-Through non-transient, Inner Non-cacheable */
    mair |= MAIR_ATTR_SET(MAKE_MAIR_NORMAL_MEMORY(MAIR_NORM_NC,MAIR_NORM_NC), ATTR_NORMAL_NONCACHE_INDEX);
    /* 3 -> Device-nGnRnE */
    mair |= MAIR_ATTR_SET(MAIR_DEV_nGnRnE, ATTR_DEVICE_nGnRnE_INDEX);

    asm volatile("msr MAIR_EL3, %0\n dsb sy\n"::"r"(mair));

    /* TCR_EL3 */
    mair = (16UL << 0)  /* t0sz 48bit */
            | (0x0UL << 6)   /* reserved */
            | (0x0UL << 7)   /* epd0 */
            | (0x3UL << 8)   /* t0 wb cacheable */
            | (0x3UL << 10)  /* inner shareable */
            | (0x2UL << 12)  /* t0 outer shareable */
            | (0x0UL << 14)  /* t0 4K */
            | (16UL << 16)   /* t1sz 48bit */
            | (0x0UL << 22)  /* define asid use ttbr0.asid */
            | (0x0UL << 23)  /* epd1 */
            | (0x3UL << 24)  /* t1 inner wb cacheable */
            | (0x3UL << 26)  /* t1 outer wb cacheable */
            | (0x2UL << 28)  /* t1 outer shareable */
            | (0x2UL << 30)  /* t1 4k */
            | (0x1UL << 32)  /* 001b 64GB PA */
            | (0x0UL << 35)  /* reserved */
            | (0x1UL << 36)  /* as: 0:8bit 1:16bit */
            | (0x0UL << 37)  /* tbi0 */
            | (0x0UL << 38); /* tbi1 */
    asm volatile("msr TCR_EL3, %0\n"::"r"(mair));
}
